﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Arsenal2
{
	public partial class Form1 : Form
	{
		void Log(String S)
		{
			File.AppendAllText("log.txt", S + "\n");
		}
		ProcessMemory PM;

		List<unit> _Units = new List<unit>();
		Dictionary<String, unit> Units = new Dictionary<string, unit>();

		const int address_mailobj = 0x004b91d4;
		const int recordlength = 0x54;
		const int firstoffset = 0x22;
		const int numunit = 55;

		public Form1(ProcessMemory pm)
		{
			InitializeComponent();
			PM = pm;
		}

		private void button1_Click(object sender, EventArgs e)
		{
			panel1.Controls.Clear();
			Units.Clear();
			listBox1.Items.Clear();
			for (int i = 0; i < numunit; i++)
			{
				int A = address_mailobj + firstoffset + i * recordlength;

				unit u = new unit(PM, A);
				Units.Add(u.Name, u);
				_Units.Add(u);
				Log("Unit \"" + u.Name + "\" Added");
				byte[] mo = PM.ReadBytes(A, 25);
				String N = "";
				for (int j = 0; j < 25 && mo[j] != 0; j++)
					N += (char)mo[j];

				byte[] pre = PM.ReadBytes(A - 22, 22);

				//Console.Write(N+"\t");
				//for (int n = 0; n < 18; n++)
				//	Console.Write(pre[n].ToString("X2") + "\t");
				//Console.WriteLine();
				byte[] post = PM.ReadBytes(A + 20, recordlength - 17 - 20);
				String Pre = BitConverter.ToString(pre);
				String Post = BitConverter.ToString(post);

				byte speed = pre[pre.Length - 5];
				byte armor = pre[pre.Length - 6];
				listBox1.Items.Add(A.ToString("X8") + " (Spd: " + speed + ")(Arm: " + armor + ") " + Pre + " " + N.PadRight(25) + " " + Post);
				Panel P = new Panel();
				P.AutoScroll = true;
				P.Size = new Size(600, 80);
				P.Location = new Point(0, i * 80);
				Controls.Add(P);

				Label L = new Label();
				L.Text = u.Name + "\n" + u.Address.ToString("X8");
				L.AutoSize = true;
				L.Location = new Point(12, 12);
				P.Controls.Add(L);
				P.Tag = u;

				AddControl(P, "gold", 70, 5, 50);
				AddControl(P, "iron", 70, 30, 50);
				AddControl(P, "fuel", 70, 55, 50);
				AddControl(P, "time", 130, 5, 30);

				AddControl(P, "hp", 230, 5, 40);
				AddControl(P, "armor", 230, 30, 40);
				DrawPanel(P);
				Button cost = new Button();
				cost.Location = new Point(130, 30);
				cost.Text = "Set cost";

				cost.Click += new EventHandler(cost_Click);
				P.Controls.Add(cost);
				P.BackColor = i % 2 == 0 ? Color.LightSkyBlue : Color.LightYellow;
				panel1.Controls.Add(P);
			}
		}
		void DrawPanel(Panel P)
		{
			unit u = (unit)P.Tag;
			P.Controls["E_gold"].Text = u.gold.ToString();
			P.Controls["E_iron"].Text = u.iron.ToString();
			P.Controls["E_fuel"].Text = u.fuel.ToString();
			P.Controls["E_time"].Text = u.time.ToString();

			P.Controls["E_hp"].Text = u.hp.ToString();
			P.Controls["E_armor"].Text = u.armor.ToString();
		}
		void cost_Click(object sender, EventArgs e)
		{
			Button cost = sender as Button;
			Panel P = cost.Parent as Panel;
			unit u = (unit)P.Tag;
			TextBox Gold = P.Controls["E_gold"] as TextBox;
			TextBox Iron = P.Controls["E_iron"] as TextBox;
			TextBox Fuel = P.Controls["E_fuel"] as TextBox;
			TextBox Time = P.Controls["E_time"] as TextBox;
			ushort gold = ushort.Parse(Gold.Text);
			ushort iron = ushort.Parse(Iron.Text);
			ushort fuel = ushort.Parse(Fuel.Text);
			ushort time = ushort.Parse(Time.Text);
			u.SetGold(gold);
			u.SetIron(iron);
			u.SetFuel(fuel);
			u.SetTime(time);
			DrawPanel(P);
		}
		void AddControl(Panel P, String name, int X, int Y, int W)
		{
			TextBox T = new TextBox();
			T.Name = "E_" + name;
			T.Location = new Point(X, Y);
			T.Width = W;
			P.Controls.Add(T);
		}
		private void button2_Click(object sender, EventArgs e)
		{
			for (ushort i = 0; i < 40; i++)
			{
				tech t = new tech(i, PM);
				t.SetGold((ushort)(i + 1));
				t.SetTime(2);
			}
		}

		private void button3_Click(object sender, EventArgs e)
		{
			foreach (var U in Units)
			{
				U.Value.SetPoint(255);
				U.Value.SetTime((ushort)(Math.Max(3, U.Value.time / 5)));
			}
			var u1 = Units["Lite Tank"];
			u1.SetPoint(5);
			u1.SetParano();
			u1.SetPoint(1);
			u1.SetHP(1);
			u1.SetArmor(127);
			u1.SetTime(3);
			var u2 = Units["DCA Truck"];
			u2.SetPoint(5);
			u2.SetParano();
			u2.SetPoint(1);
			u2.SetHP(1);
			u2.SetArmor(127);
			u2.SetTime(3);
		}

		private void button4_Click(object sender, EventArgs e)
		{
			foreach (unit u in Units.Values)
			{
				u.SetPoint(255);
				u.SetTime(3);
				u.SetHP(70);
				u.SetGold((ushort)(u.gold / 10));
				u.SetIron((ushort)(u.iron / 10));
			}
			button1_Click(null, null);
		}

		private void button6_Click(object sender, EventArgs e)
		{
			List<unit> U = new List<unit>();
			U.Add(Units["Heavy Bomber"]);
			U.Add(Units["Air HvyBombr"]);
			U.Add(Units["Fortress"]);
			U.Add(Units["Air Fortress"]);
			U.Add(Units["Tac Bomber"]);
			U.Add(Units["Air TacBombr"]);
			U.Add(Units["Fighter"]);
			U.Add(Units["Air Fighter"]);
			U.Add(Units["Navy Fighter"]);
			U.Add(Units["Air NavFight"]);
			foreach (unit u in U)
			{
				u.SetFuel(200);
				u.SetHP(500);
			}
		}

		private void button5_Click(object sender, EventArgs e)
		{
			unit cruiser = Units["Cruiser"];
			cruiser.SetPoint(255);
			cruiser.SetHP(10);
			PM.WriteByte(cruiser.Address + 25, 0xFF);
			unit destroyer = Units["Destroyer"];
			destroyer.SetPoint(255);
			destroyer.SetHP(10);
			PM.WriteByte(destroyer.Address + 25, 0xFF);
		}

		private void button7_Click(object sender, EventArgs e)
		{
			List<unit> u = new List<unit>();
			u.Add(Units["DCA Truck"]);
			u.Add(Units["Lite Tank"]);
			u.Add(Units["Submarine"]);

			foreach(var uu in u)
			{
				uu.SetParano();
				uu.SetHP(1);
				uu.SetArmor(127);
			}
		}

		private void listBox1_DoubleClick(object sender, EventArgs e)
		{
			if (listBox1.SelectedIndex > -1)
				new fUnit(_Units[listBox1.SelectedIndex]).ShowDialog();
		}
	}

	public class tech
	{
		public const int papersobj = 0x004C3820;

		public int Order;
		ProcessMemory PM;
		public String Name;
		public short ptr;
		public ushort time;
		public ushort gold;
		public tech(int order, ProcessMemory pm)
		{
			Order = order;
			PM = pm;
			int Base = papersobj + 16 + order * 20;
			ptr = pm.ReadInt16(Base);
			time = pm.ReadUInt16(Base + 2);
			gold = pm.ReadUInt16(Base + 4);

			Console.WriteLine("Tech #" + ptr + " T:" + time + " G:" + gold);
		}
		public void SetGold(ushort value)
		{
			gold = value;
			int Base = papersobj + 16 + Order * 20 + 4;
			PM.WriteUInt16(Base, value);
		}
		public void SetTime(ushort value)
		{
			time = value;
			int Base = papersobj + 16 + Order * 20 + 2;
			PM.WriteUInt16(Base, value);
		}
	}
}